package com.henry.xman.ui.datastore

import com.henry.xman.bean.XManConfigService
import com.henry.xman.util.CommonUtil
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.openapi.ui.Messages
import com.intellij.ui.components.JBList
import com.intellij.ui.components.JBScrollPane
import org.apache.commons.lang.StringEscapeUtils
import java.awt.BorderLayout
import java.awt.Dimension
import java.nio.charset.Charset
import javax.swing.*

/**
 * Date  2022/11/29.
 * Author henry.jia
 * Description
 */
class DataStorePanel(private val project: Project) : DialogWrapper(project) {
    private var path = ""
    private var cmdDir = ""
    private var jList: JBList<String>? = null

    init {
        //一定要先调用init()
        init()
        title = "DataStore预览"
        isModal = true
        pack()
        setSize(800, 600)
    }

    override fun createNorthPanel(): JComponent {
        return JPanel().apply {
            add(JButton().apply {
                text = "选择DataStore文件"
                addActionListener {
                    setDataStorePath()
                }
            })
        }
    }

    override fun createCenterPanel(): JComponent? {
        jList = JBList<String>().apply {
            setBounds(120, 50, 100, 50)
        }
        val scrollPane = JBScrollPane(jList).apply {
            preferredSize = Dimension(720, 480)
            verticalScrollBarPolicy = ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS
            isWheelScrollingEnabled = true
        }
        return JPanel().apply {
            add(scrollPane, BorderLayout.CENTER)
        }
    }

    /**
     * 设置路径
     */
    private fun setDataStorePath() {
        val chooser = JFileChooser().apply {
            fileSelectionMode = JFileChooser.FILES_ONLY
        }
        val flag = chooser.showOpenDialog(null)
        val file = chooser.selectedFile
        if (file.isFile) {
            path = file.absolutePath
        }
        if (flag == JFileChooser.APPROVE_OPTION) {
            findProtoc()
        }
    }

    /**
     * 解析DataStore pb文件
     * todo 解析key-value  tree
     */
    private fun findProtoc() {
        if (path.isEmpty()) {
            CommonUtil.showMsgTip("DataStore path is null", "Error")
            return
        }
        val config = XManConfigService.getInstance()?.state
        if (config?.protocPath.isNullOrEmpty()) {
            cmdDir = JOptionPane.showInputDialog(
                null,
                "请输入protoc路径：\n可以cmd中运行'where protoc'查看路径   ",
                "title",
                JOptionPane.PLAIN_MESSAGE
            )
            config?.apply {
                protocPath = cmdDir
                XManConfigService.getInstance()?.loadState(this)
            }
        } else {
            cmdDir = config?.protocPath ?: ""
        }

        if (cmdDir.isNotEmpty()) {
            decode()
        }
    }

    private fun decode() {
        try {
            val command = """${cmdDir.trim()} --decode_raw < ${StringEscapeUtils.escapeJava(path)}"""

            val process = Runtime.getRuntime().exec(CommonUtil.getOsCommand(command))
            val errorStream = process.errorStream.readAllBytes().toString(Charset.defaultCharset())
            if (errorStream.isNotEmpty()) {
                println(errorStream)
                Messages.showMessageDialog(errorStream, "Error", Messages.getInformationIcon())
                return
            }

            val inStream = process.inputStream.readAllBytes().toString(Charset.defaultCharset())
            //  1: "agree_state"  格式：1：key
            //  2 {                    2{  不定值:value }
            //    1: 1
            //  }
            val keyValues = inStream.split("1 {").filter {
                it.isNotEmpty()
            }.map {
                //去掉前后空格、}
                it.substring(1, it.length - 2)
            }.map {
                val array = it.split("2 {")
                val key = array[0].substring(array[0].indexOfFirst { it == '"' }).trim()
                val value = array[1].substring(array[1].indexOf(":") + 1).trim().dropLast(1).trim()
                "K-V:$key - $value"
            }
            jList?.setListData(keyValues.toTypedArray())
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}